package ga.selectionMethods;

import ga.GARun;
import ga.individuals.Individual;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class Tournaments implements SelectionReplacementMethod {
	/* cantidad de individuos al azar que seleccionan por torneo (t) */
	private Integer numberOfPlayers;
	
	/* cantidad de individuos a seleccionar (k) */
	private Integer numberOfTournaments;
	
	public Tournaments (Integer k, Integer t) throws IllegalArgumentException {
		if (k < 0 || k > GARun.popSize || t < 0 || t > GARun.popSize) {
			throw new IllegalArgumentException("Invalid number of elements to be chosen or number of tournaments");
		}
		this.numberOfPlayers = t;
		this.numberOfTournaments = k;
	}
	
	@Override
	public Collection<Individual> method(Collection<Individual> individuals) {
		List<Individual> listIndividuals = new ArrayList<Individual>(individuals);
		List<Individual> selection = new ArrayList<Individual>();
		List<Individual> rndSelection = new ArrayList<Individual>();
		Random chooser;
		
		for (int i = 0 ; i < numberOfTournaments; i++) {
			/* Reinstancio Random por cada torneo */
			chooser = new Random(System.currentTimeMillis());
			for (int j = 0 ; j < numberOfPlayers ; j++) {
				/* Agrega un individuo al azar (puede repetirse) de entre todos los posibles */
				rndSelection.add(listIndividuals.get(chooser.nextInt(listIndividuals.size())));
			}
			/* Terminada la seleccion de los individuos al azar, se queda con el mas apto (ganador del torneo)
			 * y prosigue con el siguiente torneo
			 */
			Collections.sort(rndSelection);
			selection.add(rndSelection.get(rndSelection.size() - 1));
			rndSelection.clear();
		}
		
		return selection;
	}

}
